package ch.cern



import org.junit.*
import grails.test.mixin.*

@TestFor(PointController)
@Mock([Point, Map, Tag])
class PointControllerTests {


    def populateValidParams(params) {
      assert params != null
      def map = new Map(name: 'Dubna', createdOn: new Date() -1500)
      map.save(failOnError: true)
      params["title"] = "Title"
      params["createdOn"] = new Date()
      params["description"] = "Description"
      params["map"] = map
    }

    void testIndex() {
        controller.index()
        assert "/point/list" == response.redirectedUrl
    }

    void testList() {

        def model = controller.list()

        assert model.pointInstanceList.size() == 0
        assert model.pointInstanceTotal == 0
    }

    void testCreate() {
       def model = controller.create()

       assert model.pointInstance != null
    }

    void testSave() {
        controller.save()

        assert model.pointInstance != null
        assert view == '/point/create'

        response.reset()

        populateValidParams(params)
        controller.save()

        assert response.redirectedUrl == '/point/show/1'
        assert controller.flash.message != null
        assert Point.count() == 1
    }

    void testShow() {
        controller.show()

        assert flash.message != null
        assert response.redirectedUrl == '/point/list'


        populateValidParams(params)
        def point = new Point(params)

        assert point.save() != null

        params.id = point.id

        def model = controller.show()

        assert model.pointInstance == point
    }

    void testEdit() {
        controller.edit()

        assert flash.message != null
        assert response.redirectedUrl == '/point/list'


        populateValidParams(params)
        def point = new Point(params)

        assert point.save() != null

        params.id = point.id

        def model = controller.edit()

        assert model.pointInstance == point
    }

    void testUpdate() {
        controller.update()

        assert flash.message != null
        assert response.redirectedUrl == '/point/list'

        response.reset()


        populateValidParams(params)
        def point = new Point(params)

        assert point.save() != null

        // test invalid parameters in update
        params.id = point.id
        params.title = null

        controller.update()

        assert view == "/point/edit"
        assert model.pointInstance != null

        point.clearErrors()

        populateValidParams(params)
        controller.update()

        assert response.redirectedUrl == "/point/show/$point.id"
        assert flash.message != null

        //test outdated version number
        response.reset()
        point.clearErrors()

        populateValidParams(params)
        params.id = point.id
        params.version = -1
        controller.update()

        assert view == "/point/edit"
        assert model.pointInstance != null
        assert model.pointInstance.errors.getFieldError('version')
        assert flash.message != null
    }

    void testDelete() {
        controller.delete()
        assert flash.message != null
        assert response.redirectedUrl == '/point/list'

        response.reset()

        populateValidParams(params)
        def point = new Point(params)

        assert point.save() != null
        assert Point.count() == 1

        params.id = point.id

        controller.delete()

        assert Point.count() == 0
        assert Point.get(point.id) == null
        assert response.redirectedUrl == '/point/list'
    }

  void testAll() {
    BootStrapUnit.bootStrap()
    controller.pointService = new PointService()

    //default call without any parameters
    def model = controller.all()

    //assert default values
    def formatStr = 'dd/MMM/yyyy'
    def lastYear = (new Date()-1500)
    def nextWeek = (new Date() +7)
    assert model.fromDate.format(formatStr) == lastYear.format(formatStr)
    assert model.toDate.format(formatStr) == nextWeek.format(formatStr)
    assert model.points.size() == 4
    assert model.tags.size() == 4

    //Only restaurant
    def restoTag = Tag.findByTag("restaurant")
    params.tags = [restoTag.id]
    model = controller.all()
    assert model.tags == [restoTag]
    assert model.points.size() == 2

    //pass another from date
    def fromDate = (new Date() - 365)
    params.fromDate = fromDate
    model = controller.all()
    assert model.points.size() == 1
    assert model.fromDate == fromDate

    //add another tag
    def workTag = Tag.findByTag("work")
    params.tags = [restoTag.id, workTag.id]
    fromDate = (new Date() - 2000)
    params.fromDate = fromDate
    model = controller.all()
    assert model.tags.sort{it.tag} == [restoTag, workTag]
    assert model.points.size() == 4

    //restrict enddate
    def oldToDate = fromDate + 1
    params.toDate = oldToDate
    model = controller.all()
    assert model.tags.sort{it.tag} == [restoTag, workTag]
    assert model.points.size() == 0
    assert model.fromDate == fromDate

  }

}
